require('cutils')
require('xlua')
p = xlua.Profiler()

function test_roulette_sampling()
	--temp = torch.rand(50000, 100)
	--probs = temp:cdiv(torch.repeatTensor(torch.sum(temp,1),temp:size(1),1))
	--p:lap('prob')

	--print(probs)
	--p:start('sampling')
	--for i = 1,100 do
--		t = roulette_sampling(probs)
	--end
end

function test_multi_mv()
	embdim = 50
	datasize = 1000 
	ntypes = 5

	M = torch.randn(datasize, ntypes, embdim)
	v = torch.randn(ntypes, datasize):t()
	u = torch.zeros(datasize, embdim)

	for iter = 1,1000 do
		p:start('c')
		local u1 = multi_vm(v, M)
		p:lap('c')

		p:start('lua')
		for i = 1,datasize do
			u[{{i},{}}]:copy(v[{{i},{}}] * M[{i,{},{}}])
		end
		p:lap('lua')

		for i = 1,datasize do
			u[{{i},{}}]:add(-u1[{{i},{}}])
		end
		print(u:abs():sum() / torch.numel(u))

		p:printAll()
		collectgarbage()
	end
end

test_multi_mv()

function test_multi_oprod()
	n = 10000
	M = torch.zeros(n, 100, 200);
	v = torch.rand(n, 200);
	u = torch.rand(n, 100);

	multi_oprod(u, v)
	p:start('c')
	M1 = multi_oprod(u, v)
	p:lap('c')

	p:start('lua')

	for i = 1,n do
		M[{i,{},{}}]:addr(u[{i,{}}], v[{i,{}}])
		M[{i,{},{}}]:add(torch.mul(M1[{i,{},{}}],-1))
	end

	print(M:abs():sum())

	p:lap('lua')

	--print(t)
	p:printAll()
end

--test_multi_oprod()

function test_indep_chain_metropolis_hastings()
	nstates = 100000;
	prob = torch.linspace(1,nstates,nstates)
	prob:mul(1. / prob:sum())
	--print(prob)
	states = torch.rand(100, 100):mul(nstates):add(1):long()
	ratios = torch.mul(states:double(), 1. / nstates)
	p:start('MH')
	indep_chain_metropolis_hastings(states, ratios)
	p:lap('MH')
	p:printAll()
	
	--sample = states[{{5000,-1},{}}]
	--sum = 0
	--for i = 1,nstates do
	--	temp = torch.eq(sample, i):double()
	--	sum = sum + math.abs(temp:sum() / torch.numel(sample) - prob[{i}])
	--end
	--print(sum)
end

function test_alias_sampling()
	nstates = 5;
	prob = torch.linspace(1,nstates,nstates)
	prob:mul(1. / prob:sum())
	print(prob)

	alias, prob = init_alias_sampling(prob)

	nsample = 10
	p:start('gen')
	for i = 1,5 do
		sample = gen_alias_sampling(alias, prob, nsample)
		print(sample)
	end
	p:lap('gen')
	p:printAll()
	--print(sample)
	
	stat = torch.zeros(nstates)
	for i = 1,nsample do
		local range = {sample[{i}]}
		stat[range] = stat[range] + 1
	end
	stat:mul( 1. / stat:sum() )
	print(stat)
end

--test_alias_sampling()


